payload-plugin-newsletter 0.25.1 → 0.25.2

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.
@@ -1501,7 +1501,7 @@ var createSendBroadcastEndpoint = (config, collectionSlug) => {
1501
1501
  return {
1502
1502
  path: "/:id/send",
1503
1503
  method: "post",
1504
- handler: async (req) => {
1504
+ handler: (async (req) => {
1505
1505
  try {
1506
1506
  const auth = await requireAdmin(req, config);
1507
1507
  if (!auth.authorized) {
@@ -1575,7 +1575,7 @@ var createSendBroadcastEndpoint = (config, collectionSlug) => {
1575
1575
  error: "Failed to send broadcast"
1576
1576
  }, { status: 500 });
1577
1577
  }
1578
- }
1578
+ })
1579
1579
  };
1580
1580
  };
1581
1581
 
@@ -1585,7 +1585,7 @@ var createScheduleBroadcastEndpoint = (config, collectionSlug) => {
1585
1585
  return {
1586
1586
  path: "/:id/schedule",
1587
1587
  method: "post",
1588
- handler: async (req) => {
1588
+ handler: (async (req) => {
1589
1589
  try {
1590
1590
  const auth = await requireAdmin(req, config);
1591
1591
  if (!auth.authorized) {
@@ -1679,7 +1679,7 @@ var createScheduleBroadcastEndpoint = (config, collectionSlug) => {
1679
1679
  error: "Failed to schedule broadcast"
1680
1680
  }, { status: 500 });
1681
1681
  }
1682
- }
1682
+ })
1683
1683
  };
1684
1684
  };
1685
1685
 
@@ -1688,7 +1688,7 @@ var createTestBroadcastEndpoint = (config, collectionSlug) => {
1688
1688
  return {
1689
1689
  path: "/:id/test",
1690
1690
  method: "post",
1691
- handler: async (req) => {
1691
+ handler: (async (req) => {
1692
1692
  try {
1693
1693
  const auth = await requireAdmin(req, config);
1694
1694
  if (!auth.authorized) {
@@ -1762,7 +1762,7 @@ var createTestBroadcastEndpoint = (config, collectionSlug) => {
1762
1762
  error: "Failed to send test email"
1763
1763
  }, { status: 500 });
1764
1764
  }
1765
- }
1765
+ })
1766
1766
  };
1767
1767
  };
1768
1768
 
@@ -1851,7 +1851,7 @@ var createBroadcastPreviewEndpoint = (config, _collectionSlug) => {
1851
1851
  return {
1852
1852
  path: "/preview",
1853
1853
  method: "post",
1854
- handler: async (req) => {
1854
+ handler: (async (req) => {
1855
1855
  try {
1856
1856
  const data = await (req.json?.() || Promise.resolve({}));
1857
1857
  const { content, preheader, subject, documentData } = data;
@@ -1891,7 +1891,7 @@ var createBroadcastPreviewEndpoint = (config, _collectionSlug) => {
1891
1891
  error: "Failed to generate email preview"
1892
1892
  }, { status: 500 });
1893
1893
  }
1894
- }
1894
+ })
1895
1895
  };
1896
1896
  };
1897
1897
 
@@ -2236,10 +2236,6 @@ var createBroadcastsCollection = (pluginConfig) => {
2236
2236
  async ({ doc, operation, req, previousDoc }) => {
2237
2237
  if (!hasProviders) return doc;
2238
2238
  if (operation === "create") {
2239
- if (!doc.subject || !doc.contentSection?.content) {
2240
- req.payload.logger.info("Skipping provider sync - broadcast has no subject or content yet");
2241
- return doc;
2242
- }
2243
2239
  try {
2244
2240
  const providerConfig = await getBroadcastConfig(req, pluginConfig);
2245
2241
  if (!providerConfig || !providerConfig.token) {
@@ -2248,45 +2244,32 @@ var createBroadcastsCollection = (pluginConfig) => {
2248
2244
  }
2249
2245
  const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
2250
2246
  const provider = new BroadcastApiProvider2(providerConfig);
2251
- req.payload.logger.info("Populating media fields and converting content to HTML...");
2252
- const populatedContent = await populateMediaFields(doc.contentSection?.content, req.payload, pluginConfig);
2253
- const emailPreviewConfig = pluginConfig.customizations?.broadcasts?.emailPreview;
2254
- const htmlContent = await convertToEmailSafeHtml(populatedContent, {
2255
- wrapInTemplate: emailPreviewConfig?.wrapInTemplate ?? true,
2256
- customWrapper: emailPreviewConfig?.customWrapper,
2257
- preheader: doc.contentSection?.preheader,
2258
- subject: doc.subject,
2259
- documentData: doc,
2260
- // Pass entire document
2261
- customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
2262
- });
2263
- if (!htmlContent || htmlContent.trim() === "") {
2264
- req.payload.logger.info("Skipping provider sync - content is empty after conversion");
2265
- return doc;
2266
- }
2247
+ const subject = doc.subject || `Draft Broadcast ${(/* @__PURE__ */ new Date()).toISOString()}`;
2248
+ const htmlContent = doc.contentSection?.content ? await convertToEmailSafeHtml(
2249
+ await populateMediaFields(doc.contentSection.content, req.payload, pluginConfig),
2250
+ {
2251
+ wrapInTemplate: pluginConfig.customizations?.broadcasts?.emailPreview?.wrapInTemplate ?? true,
2252
+ customWrapper: pluginConfig.customizations?.broadcasts?.emailPreview?.customWrapper,
2253
+ preheader: doc.contentSection?.preheader,
2254
+ subject,
2255
+ documentData: doc,
2256
+ customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
2257
+ }
2258
+ ) : "<p>Draft content - to be updated</p>";
2267
2259
  const createData = {
2268
- name: doc.subject,
2269
- // Use subject as name since we removed the name field
2270
- subject: doc.subject,
2271
- preheader: doc.contentSection?.preheader,
2260
+ name: subject,
2261
+ // Use subject as name
2262
+ subject,
2263
+ preheader: doc.contentSection?.preheader || "",
2272
2264
  content: htmlContent,
2273
- trackOpens: doc.settings?.trackOpens,
2274
- trackClicks: doc.settings?.trackClicks,
2265
+ trackOpens: doc.settings?.trackOpens ?? true,
2266
+ trackClicks: doc.settings?.trackClicks ?? true,
2275
2267
  replyTo: doc.settings?.replyTo || providerConfig.replyTo,
2276
- audienceIds: doc.audienceIds?.map((a) => a.audienceId)
2268
+ audienceIds: doc.audienceIds?.map((a) => a.audienceId) || []
2277
2269
  };
2278
- req.payload.logger.info("Creating broadcast with data:", {
2279
- name: createData.name,
2270
+ req.payload.logger.info("Creating broadcast in provider with minimal data to establish association", {
2280
2271
  subject: createData.subject,
2281
- preheader: createData.preheader || "NONE",
2282
- contentLength: htmlContent ? htmlContent.length : 0,
2283
- contentPreview: htmlContent ? htmlContent.substring(0, 100) + "..." : "EMPTY",
2284
- trackOpens: createData.trackOpens,
2285
- trackClicks: createData.trackClicks,
2286
- replyTo: createData.replyTo,
2287
- audienceIds: createData.audienceIds || [],
2288
- apiUrl: providerConfig.apiUrl,
2289
- hasToken: !!providerConfig.token
2272
+ hasActualContent: !!doc.contentSection?.content
2290
2273
  });
2291
2274
  const providerBroadcast = await provider.create(createData);
2292
2275
  await req.payload.update({
@@ -2298,40 +2281,14 @@ var createBroadcastsCollection = (pluginConfig) => {
2298
2281
  },
2299
2282
  req
2300
2283
  });
2284
+ req.payload.logger.info(`Broadcast ${doc.id} created in provider with ID ${providerBroadcast.id}`);
2301
2285
  return {
2302
2286
  ...doc,
2303
2287
  providerId: providerBroadcast.id,
2304
2288
  providerData: providerBroadcast.providerData
2305
2289
  };
2306
2290
  } catch (error) {
2307
- req.payload.logger.error("Raw error from broadcast provider:");
2308
- req.payload.logger.error(error);
2309
- if (error instanceof Error) {
2310
- req.payload.logger.error("Error is instance of Error:", {
2311
- message: error.message,
2312
- stack: error.stack,
2313
- name: error.name,
2314
- // If it's a BroadcastProviderError, it might have additional details
2315
- ...error.details,
2316
- // Check if it's a fetch response error
2317
- ...error.response,
2318
- ...error.data,
2319
- ...error.status,
2320
- ...error.statusText
2321
- });
2322
- } else if (typeof error === "string") {
2323
- req.payload.logger.error("Error is a string:", error);
2324
- } else if (error && typeof error === "object") {
2325
- req.payload.logger.error("Error is an object:", JSON.stringify(error, null, 2));
2326
- } else {
2327
- req.payload.logger.error("Unknown error type:", typeof error);
2328
- }
2329
- req.payload.logger.error("Failed broadcast document:", {
2330
- id: doc.id,
2331
- subject: doc.subject,
2332
- hasContent: !!doc.contentSection?.content,
2333
- contentType: doc.contentSection?.content ? typeof doc.contentSection.content : "none"
2334
- });
2291
+ req.payload.logger.error("Failed to create broadcast in provider during initial creation:", error);
2335
2292
  return doc;
2336
2293
  }
2337
2294
  }
@@ -2351,61 +2308,8 @@ var createBroadcastsCollection = (pluginConfig) => {
2351
2308
  const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
2352
2309
  const provider = new BroadcastApiProvider2(providerConfig);
2353
2310
  if (!doc.providerId) {
2354
- if (!doc.subject || !doc.contentSection?.content) {
2355
- req.payload.logger.info("Still missing required fields for provider sync");
2356
- return doc;
2357
- }
2358
- req.payload.logger.info("Creating broadcast in provider (deferred from initial create)...");
2359
- const populatedContent = await populateMediaFields(doc.contentSection?.content, req.payload, pluginConfig);
2360
- const emailPreviewConfig = pluginConfig.customizations?.broadcasts?.emailPreview;
2361
- const htmlContent = await convertToEmailSafeHtml(populatedContent, {
2362
- wrapInTemplate: emailPreviewConfig?.wrapInTemplate ?? true,
2363
- customWrapper: emailPreviewConfig?.customWrapper,
2364
- preheader: doc.contentSection?.preheader,
2365
- subject: doc.subject,
2366
- documentData: doc,
2367
- // Pass entire document
2368
- customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
2369
- });
2370
- if (!htmlContent || htmlContent.trim() === "") {
2371
- req.payload.logger.info("Skipping provider sync - content is empty after conversion");
2372
- return doc;
2373
- }
2374
- const createData = {
2375
- name: doc.subject,
2376
- subject: doc.subject,
2377
- preheader: doc.contentSection?.preheader,
2378
- content: htmlContent,
2379
- trackOpens: doc.settings?.trackOpens,
2380
- trackClicks: doc.settings?.trackClicks,
2381
- replyTo: doc.settings?.replyTo || providerConfig.replyTo,
2382
- audienceIds: doc.audienceIds?.map((a) => a.audienceId)
2383
- };
2384
- req.payload.logger.info("Creating broadcast with data:", {
2385
- name: createData.name,
2386
- subject: createData.subject,
2387
- preheader: createData.preheader || "NONE",
2388
- contentLength: htmlContent ? htmlContent.length : 0,
2389
- contentPreview: htmlContent ? htmlContent.substring(0, 100) + "..." : "EMPTY",
2390
- apiUrl: providerConfig.apiUrl,
2391
- hasToken: !!providerConfig.token
2392
- });
2393
- const providerBroadcast = await provider.create(createData);
2394
- await req.payload.update({
2395
- collection: "broadcasts",
2396
- id: doc.id,
2397
- data: {
2398
- providerId: providerBroadcast.id,
2399
- providerData: providerBroadcast.providerData
2400
- },
2401
- req
2402
- });
2403
- req.payload.logger.info(`Broadcast ${doc.id} created in provider successfully (deferred)`);
2404
- return {
2405
- ...doc,
2406
- providerId: providerBroadcast.id,
2407
- providerData: providerBroadcast.providerData
2408
- };
2311
+ req.payload.logger.warn(`Broadcast ${doc.id} has no providerId - provider sync skipped. This shouldn't happen with immediate creation.`);
2312
+ return doc;
2409
2313
  }
2410
2314
  if (doc.providerId) {
2411
2315
  const capabilities = provider.getCapabilities();