payload-plugin-newsletter 0.14.3 → 0.15.1
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 +55 -0
- package/README.md +47 -0
- package/dist/collections.cjs +2124 -0
- package/dist/collections.cjs.map +1 -0
- package/dist/collections.d.cts +8 -0
- package/dist/collections.d.ts +8 -0
- package/dist/collections.js +2128 -0
- package/dist/collections.js.map +1 -0
- package/dist/fields.cjs +498 -115
- package/dist/fields.cjs.map +1 -1
- package/dist/fields.d.cts +30 -4
- package/dist/fields.d.ts +30 -4
- package/dist/fields.js +481 -114
- package/dist/fields.js.map +1 -1
- package/dist/index.cjs +305 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +305 -118
- package/dist/index.js.map +1 -1
- package/dist/types.d.cts +15 -2
- package/dist/types.d.ts +15 -2
- package/package.json +11 -1
package/dist/fields.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fields/emailContent.ts"],"sourcesContent":["import { \n BoldFeature,\n ItalicFeature,\n UnderlineFeature,\n StrikethroughFeature,\n LinkFeature,\n OrderedListFeature,\n UnorderedListFeature,\n HeadingFeature,\n ParagraphFeature,\n AlignFeature,\n BlockquoteFeature,\n BlocksFeature,\n UploadFeature,\n FixedToolbarFeature,\n InlineToolbarFeature,\n lexicalEditor,\n} from '@payloadcms/richtext-lexical'\nimport type { RichTextField } from 'payload'\n\n/**\n * Email-safe features for Lexical editor\n * Only includes features that render consistently across email clients\n */\n// Using any[] here because Payload's FeatureProviderServer type is complex\n// and varies between versions. The features are properly typed by Payload internally.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const emailSafeFeatures: any[] = [\n // Toolbars\n FixedToolbarFeature(), // Fixed toolbar at the top\n InlineToolbarFeature(), // Floating toolbar when text is selected\n \n // Basic text formatting\n BoldFeature(),\n ItalicFeature(),\n UnderlineFeature(),\n StrikethroughFeature(),\n \n // Links with enhanced configuration\n LinkFeature({\n fields: [\n {\n name: 'url',\n type: 'text',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'newTab',\n type: 'checkbox',\n label: 'Open in new tab',\n defaultValue: false,\n },\n ],\n }),\n \n // Lists\n OrderedListFeature(),\n UnorderedListFeature(),\n \n // Headings - limited to h1, h2, h3 for email compatibility\n HeadingFeature({\n enabledHeadingSizes: ['h1', 'h2', 'h3'],\n }),\n \n // Basic paragraph and alignment\n ParagraphFeature(),\n AlignFeature(),\n \n // Blockquotes\n BlockquoteFeature(),\n \n // Upload feature for images\n UploadFeature({\n collections: {\n media: {\n fields: [\n {\n name: 'caption',\n type: 'text',\n admin: {\n description: 'Optional caption for the image',\n },\n },\n {\n name: 'altText',\n type: 'text',\n label: 'Alt Text',\n required: true,\n admin: {\n description: 'Alternative text for accessibility and when image cannot be displayed',\n },\n },\n ],\n },\n },\n }),\n \n // Custom blocks for email-specific content\n BlocksFeature({\n blocks: [\n {\n slug: 'button',\n fields: [\n {\n name: 'text',\n type: 'text',\n label: 'Button Text',\n required: true,\n },\n {\n name: 'url',\n type: 'text',\n label: 'Button URL',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'style',\n type: 'select',\n label: 'Button Style',\n defaultValue: 'primary',\n options: [\n { label: 'Primary', value: 'primary' },\n { label: 'Secondary', value: 'secondary' },\n { label: 'Outline', value: 'outline' },\n ],\n },\n ],\n interfaceName: 'EmailButton',\n labels: {\n singular: 'Button',\n plural: 'Buttons',\n },\n },\n {\n slug: 'divider',\n fields: [\n {\n name: 'style',\n type: 'select',\n label: 'Divider Style',\n defaultValue: 'solid',\n options: [\n { label: 'Solid', value: 'solid' },\n { label: 'Dashed', value: 'dashed' },\n { label: 'Dotted', value: 'dotted' },\n ],\n },\n ],\n interfaceName: 'EmailDivider',\n labels: {\n singular: 'Divider',\n plural: 'Dividers',\n },\n },\n ],\n }),\n]\n\n/**\n * Creates an email-safe rich text field configuration\n */\nexport const createEmailContentField = (overrides?: Partial<RichTextField>): RichTextField => {\n return {\n name: 'content',\n type: 'richText',\n required: true,\n editor: lexicalEditor({\n features: emailSafeFeatures,\n }),\n admin: {\n description: 'Email content with limited formatting for compatibility',\n ...overrides?.admin,\n },\n ...overrides,\n }\n}"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUA,IAAM,oBAA2B;AAAA;AAAA,EAEtC,oBAAoB;AAAA;AAAA,EACpB,qBAAqB;AAAA;AAAA;AAAA,EAGrB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,qBAAqB;AAAA;AAAA,EAGrB,YAAY;AAAA,IACV,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,OAAO;AAAA,UACL,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AAAA;AAAA,EAGD,mBAAmB;AAAA,EACnB,qBAAqB;AAAA;AAAA,EAGrB,eAAe;AAAA,IACb,qBAAqB,CAAC,MAAM,MAAM,IAAI;AAAA,EACxC,CAAC;AAAA;AAAA,EAGD,iBAAiB;AAAA,EACjB,aAAa;AAAA;AAAA,EAGb,kBAAkB;AAAA;AAAA,EAGlB,cAAc;AAAA,IACZ,aAAa;AAAA,MACX,OAAO;AAAA,QACL,QAAQ;AAAA,UACN;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,cACL,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAO;AAAA,cACL,aAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAAA;AAAA,EAGD,cAAc;AAAA,IACZ,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,UACN;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU;AAAA,UACZ;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAO;AAAA,cACL,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,cAAc;AAAA,YACd,SAAS;AAAA,cACP,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,cACrC,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,cACzC,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,YACvC;AAAA,UACF;AAAA,QACF;AAAA,QACA,eAAe;AAAA,QACf,QAAQ;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,QAAQ;AAAA,UACN;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,YACP,cAAc;AAAA,YACd,SAAS;AAAA,cACP,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,cACjC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,cACnC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,QACA,eAAe;AAAA,QACf,QAAQ;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKO,IAAM,0BAA0B,CAAC,cAAsD;AAC5F,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,cAAc;AAAA,MACpB,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,OAAO;AAAA,MACL,aAAa;AAAA,MACb,GAAG,WAAW;AAAA,IAChB;AAAA,IACA,GAAG;AAAA,EACL;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/fields/emailContent.ts","../src/utils/blockValidation.ts","../src/fields/broadcastInlinePreview.ts","../src/fields/newsletterScheduling.ts"],"sourcesContent":["import { \n BoldFeature,\n ItalicFeature,\n UnderlineFeature,\n StrikethroughFeature,\n LinkFeature,\n OrderedListFeature,\n UnorderedListFeature,\n HeadingFeature,\n ParagraphFeature,\n AlignFeature,\n BlockquoteFeature,\n BlocksFeature,\n UploadFeature,\n FixedToolbarFeature,\n InlineToolbarFeature,\n lexicalEditor,\n} from '@payloadcms/richtext-lexical'\nimport type { RichTextField, Block } from 'payload'\nimport { createEmailSafeBlocks } from '../utils/blockValidation'\n\n/**\n * Creates email-safe features for Lexical editor with optional additional blocks\n * Only includes features that render consistently across email clients\n */\n// Using any[] here because Payload's FeatureProviderServer type is complex\n// and varies between versions. The features are properly typed by Payload internally.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const createEmailSafeFeatures = (additionalBlocks?: Block[]): any[] => {\n // Base email-safe blocks\n const baseBlocks = [\n {\n slug: 'button',\n fields: [\n {\n name: 'text',\n type: 'text',\n label: 'Button Text',\n required: true,\n },\n {\n name: 'url',\n type: 'text',\n label: 'Button URL',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'style',\n type: 'select',\n label: 'Button Style',\n defaultValue: 'primary',\n options: [\n { label: 'Primary', value: 'primary' },\n { label: 'Secondary', value: 'secondary' },\n { label: 'Outline', value: 'outline' },\n ],\n },\n ],\n interfaceName: 'EmailButton',\n labels: {\n singular: 'Button',\n plural: 'Buttons',\n },\n },\n {\n slug: 'divider',\n fields: [\n {\n name: 'style',\n type: 'select',\n label: 'Divider Style',\n defaultValue: 'solid',\n options: [\n { label: 'Solid', value: 'solid' },\n { label: 'Dashed', value: 'dashed' },\n { label: 'Dotted', value: 'dotted' },\n ],\n },\n ],\n interfaceName: 'EmailDivider',\n labels: {\n singular: 'Divider',\n plural: 'Dividers',\n },\n },\n ] as Block[]\n\n // Merge additional blocks if provided\n const allBlocks = [\n ...baseBlocks,\n ...(additionalBlocks || [])\n ]\n\n return [\n // Toolbars\n FixedToolbarFeature(), // Fixed toolbar at the top\n InlineToolbarFeature(), // Floating toolbar when text is selected\n \n // Basic text formatting\n BoldFeature(),\n ItalicFeature(),\n UnderlineFeature(),\n StrikethroughFeature(),\n \n // Links with enhanced configuration\n LinkFeature({\n fields: [\n {\n name: 'url',\n type: 'text',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'newTab',\n type: 'checkbox',\n label: 'Open in new tab',\n defaultValue: false,\n },\n ],\n }),\n \n // Lists\n OrderedListFeature(),\n UnorderedListFeature(),\n \n // Headings - limited to h1, h2, h3 for email compatibility\n HeadingFeature({\n enabledHeadingSizes: ['h1', 'h2', 'h3'],\n }),\n \n // Basic paragraph and alignment\n ParagraphFeature(),\n AlignFeature(),\n \n // Blockquotes\n BlockquoteFeature(),\n \n // Upload feature for images\n UploadFeature({\n collections: {\n media: {\n fields: [\n {\n name: 'caption',\n type: 'text',\n admin: {\n description: 'Optional caption for the image',\n },\n },\n {\n name: 'altText',\n type: 'text',\n label: 'Alt Text',\n required: true,\n admin: {\n description: 'Alternative text for accessibility and when image cannot be displayed',\n },\n },\n ],\n },\n },\n }),\n \n // Custom blocks for email-specific content\n BlocksFeature({\n blocks: allBlocks,\n }),\n ]\n}\n\n/**\n * Creates a Lexical editor configured specifically for email content\n * Processes blocks server-side to avoid client serialization issues\n */\nexport const createEmailLexicalEditor = (customBlocks: Block[] = []): any => {\n const emailSafeBlocks = createEmailSafeBlocks(customBlocks)\n \n return lexicalEditor({\n features: [\n // Toolbars\n FixedToolbarFeature(),\n InlineToolbarFeature(),\n \n // Basic text formatting\n BoldFeature(),\n ItalicFeature(),\n UnderlineFeature(),\n StrikethroughFeature(),\n \n // Links with enhanced configuration\n LinkFeature({\n fields: [\n {\n name: 'url',\n type: 'text',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'newTab',\n type: 'checkbox',\n label: 'Open in new tab',\n defaultValue: false,\n },\n ],\n }),\n \n // Lists\n OrderedListFeature(),\n UnorderedListFeature(),\n \n // Headings - limited to h1, h2, h3 for email compatibility\n HeadingFeature({\n enabledHeadingSizes: ['h1', 'h2', 'h3'],\n }),\n \n // Basic paragraph and alignment\n ParagraphFeature(),\n AlignFeature(),\n \n // Blockquotes\n BlockquoteFeature(),\n \n // Upload feature for images\n UploadFeature({\n collections: {\n media: {\n fields: [\n {\n name: 'caption',\n type: 'text',\n admin: {\n description: 'Optional caption for the image',\n },\n },\n {\n name: 'altText',\n type: 'text',\n label: 'Alt Text',\n required: true,\n admin: {\n description: 'Alternative text for accessibility and when image cannot be displayed',\n },\n },\n ],\n },\n },\n }),\n \n // Email-safe blocks (processed server-side)\n BlocksFeature({\n blocks: emailSafeBlocks,\n }),\n ],\n })\n}\n\n/**\n * Legacy export for backward compatibility\n */\nexport const emailSafeFeatures = createEmailSafeFeatures()\n\n/**\n * Creates an email-safe rich text field configuration\n */\nexport const createEmailContentField = (\n overrides?: Partial<RichTextField> & {\n additionalBlocks?: Block[]\n editor?: any // Lexical editor instance\n }\n): RichTextField => {\n // Use provided editor or create one with blocks\n const editor = overrides?.editor || createEmailLexicalEditor(overrides?.additionalBlocks)\n\n return {\n name: 'content',\n type: 'richText',\n required: true,\n editor,\n admin: {\n description: 'Email content with limited formatting for compatibility',\n ...overrides?.admin,\n },\n ...overrides,\n }\n}","import type { Block } from 'payload'\n\n/**\n * Email-incompatible block types that should be warned about\n */\nconst EMAIL_INCOMPATIBLE_TYPES = [\n 'chart',\n 'dataTable', \n 'interactive',\n 'streamable',\n 'video',\n 'iframe',\n 'form',\n 'carousel',\n 'tabs',\n 'accordion',\n 'map'\n]\n\n/**\n * Validates that blocks are email-compatible and warns about potential issues\n */\nexport const validateEmailBlocks = (blocks: Block[]): void => {\n blocks.forEach(block => {\n if (EMAIL_INCOMPATIBLE_TYPES.includes(block.slug)) {\n console.warn(`⚠️ Block \"${block.slug}\" may not be email-compatible. Consider creating an email-specific version.`)\n }\n \n // Check for complex field types that might not work in emails\n const hasComplexFields = block.fields?.some(field => {\n const complexTypes = ['code', 'json', 'richText', 'blocks', 'array']\n return complexTypes.includes(field.type)\n })\n \n if (hasComplexFields) {\n console.warn(`⚠️ Block \"${block.slug}\" contains complex field types that may not render consistently in email clients.`)\n }\n })\n}\n\n/**\n * Creates email-safe block configurations by filtering and validating blocks\n */\nexport const createEmailSafeBlocks = (customBlocks: Block[] = []): Block[] => {\n // Validate blocks\n validateEmailBlocks(customBlocks)\n \n // Base email-safe blocks that come with the plugin\n const baseBlocks: Block[] = [\n {\n slug: 'button',\n fields: [\n {\n name: 'text',\n type: 'text',\n label: 'Button Text',\n required: true,\n },\n {\n name: 'url',\n type: 'text',\n label: 'Button URL',\n required: true,\n admin: {\n description: 'Enter the full URL (including https://)',\n },\n },\n {\n name: 'style',\n type: 'select',\n label: 'Button Style',\n defaultValue: 'primary',\n options: [\n { label: 'Primary', value: 'primary' },\n { label: 'Secondary', value: 'secondary' },\n { label: 'Outline', value: 'outline' },\n ],\n },\n ],\n interfaceName: 'EmailButton',\n labels: {\n singular: 'Button',\n plural: 'Buttons',\n },\n },\n {\n slug: 'divider',\n fields: [\n {\n name: 'style',\n type: 'select',\n label: 'Divider Style',\n defaultValue: 'solid',\n options: [\n { label: 'Solid', value: 'solid' },\n { label: 'Dashed', value: 'dashed' },\n { label: 'Dotted', value: 'dotted' },\n ],\n },\n ],\n interfaceName: 'EmailDivider',\n labels: {\n singular: 'Divider',\n plural: 'Dividers',\n },\n },\n ]\n \n // Combine base blocks with custom blocks\n return [\n ...baseBlocks,\n ...customBlocks\n ]\n}","import type { Field } from 'payload'\n\nexport const createBroadcastInlinePreviewField = (): Field => {\n return {\n name: 'broadcastInlinePreview',\n type: 'ui',\n admin: {\n components: {\n Field: 'payload-plugin-newsletter/components#BroadcastInlinePreview',\n },\n },\n }\n}","import type { Field } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\n\nexport function createNewsletterSchedulingFields(\n config: NewsletterPluginConfig\n): Field[] {\n const groupName = config.features?.newsletterScheduling?.fields?.groupName || 'newsletterScheduling'\n const contentField = config.features?.newsletterScheduling?.fields?.contentField || 'content'\n const createMarkdownField = config.features?.newsletterScheduling?.fields?.createMarkdownField !== false\n\n const fields: Field[] = [\n {\n name: groupName,\n type: 'group',\n label: 'Newsletter Scheduling',\n admin: {\n condition: (data, { user }) => user?.collection === 'users', // Only show for admin users\n },\n fields: [\n {\n name: 'scheduled',\n type: 'checkbox',\n label: 'Schedule for Newsletter',\n defaultValue: false,\n admin: {\n description: 'Schedule this content to be sent as a newsletter',\n },\n },\n {\n name: 'scheduledDate',\n type: 'date',\n label: 'Send Date',\n required: true,\n admin: {\n date: {\n pickerAppearance: 'dayAndTime',\n },\n condition: (data) => data?.[groupName]?.scheduled,\n description: 'When to send this newsletter',\n },\n },\n {\n name: 'sentDate',\n type: 'date',\n label: 'Sent Date',\n admin: {\n readOnly: true,\n condition: (data) => data?.[groupName]?.sendStatus === 'sent',\n description: 'When this newsletter was sent',\n },\n },\n {\n name: 'sendStatus',\n type: 'select',\n label: 'Status',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Scheduled', value: 'scheduled' },\n { label: 'Sending', value: 'sending' },\n { label: 'Sent', value: 'sent' },\n { label: 'Failed', value: 'failed' },\n ],\n defaultValue: 'draft',\n admin: {\n readOnly: true,\n description: 'Current send status',\n },\n },\n {\n name: 'emailSubject',\n type: 'text',\n label: 'Email Subject',\n required: true,\n admin: {\n condition: (data) => data?.[groupName]?.scheduled,\n description: 'Subject line for the newsletter email',\n },\n },\n {\n name: 'preheader',\n type: 'text',\n label: 'Email Preheader',\n admin: {\n condition: (data) => data?.[groupName]?.scheduled,\n description: 'Preview text that appears after the subject line',\n },\n },\n {\n name: 'segments',\n type: 'select',\n label: 'Target Segments',\n hasMany: true,\n options: [\n { label: 'All Subscribers', value: 'all' },\n ...(config.i18n?.locales?.map(locale => ({\n label: `${locale.toUpperCase()} Subscribers`,\n value: locale,\n })) || []),\n ],\n defaultValue: ['all'],\n admin: {\n condition: (data) => data?.[groupName]?.scheduled,\n description: 'Which subscriber segments to send to',\n },\n },\n {\n name: 'testEmails',\n type: 'array',\n label: 'Test Email Recipients',\n admin: {\n condition: (data) => data?.[groupName]?.scheduled && data?.[groupName]?.sendStatus === 'draft',\n description: 'Send test emails before scheduling',\n },\n fields: [\n {\n name: 'email',\n type: 'email',\n required: true,\n },\n ],\n },\n ],\n },\n ]\n\n // Add markdown companion field if requested\n if (createMarkdownField) {\n fields.push(createMarkdownFieldInternal({\n name: `${contentField}Markdown`,\n richTextField: contentField,\n label: 'Email Content (Markdown)',\n admin: {\n position: 'sidebar',\n condition: (data: any) => Boolean(data?.[contentField] && data?.[groupName]?.scheduled),\n description: 'Markdown version for email rendering',\n readOnly: true,\n },\n }))\n }\n\n return fields\n}\n\n/**\n * Create a markdown companion field for rich text\n * This creates a virtual field that converts rich text to markdown\n */\nfunction createMarkdownFieldInternal(config: {\n name: string\n richTextField: string\n label?: string\n admin?: any\n}): Field {\n return {\n name: config.name,\n type: 'textarea',\n label: config.label || 'Markdown',\n admin: {\n ...config.admin,\n description: config.admin?.description || 'Auto-generated from rich text content',\n },\n hooks: {\n afterRead: [\n async ({ data }) => {\n // Convert rich text to markdown on read\n if (data?.[config.richTextField]) {\n try {\n const { convertLexicalToMarkdown } = await import('@payloadcms/richtext-lexical')\n return convertLexicalToMarkdown({\n data: data[config.richTextField],\n } as any)\n } catch {\n return ''\n }\n }\n return ''\n },\n ],\n beforeChange: [\n () => {\n // Don't save markdown to database\n return null\n },\n ],\n },\n }\n}"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -3761,144 +3761,323 @@ init_types();
|
|
|
3761
3761
|
|
|
3762
3762
|
// src/fields/emailContent.ts
|
|
3763
3763
|
var import_richtext_lexical = require("@payloadcms/richtext-lexical");
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3764
|
+
|
|
3765
|
+
// src/utils/blockValidation.ts
|
|
3766
|
+
var EMAIL_INCOMPATIBLE_TYPES = [
|
|
3767
|
+
"chart",
|
|
3768
|
+
"dataTable",
|
|
3769
|
+
"interactive",
|
|
3770
|
+
"streamable",
|
|
3771
|
+
"video",
|
|
3772
|
+
"iframe",
|
|
3773
|
+
"form",
|
|
3774
|
+
"carousel",
|
|
3775
|
+
"tabs",
|
|
3776
|
+
"accordion",
|
|
3777
|
+
"map"
|
|
3778
|
+
];
|
|
3779
|
+
var validateEmailBlocks = (blocks) => {
|
|
3780
|
+
blocks.forEach((block) => {
|
|
3781
|
+
if (EMAIL_INCOMPATIBLE_TYPES.includes(block.slug)) {
|
|
3782
|
+
console.warn(`\u26A0\uFE0F Block "${block.slug}" may not be email-compatible. Consider creating an email-specific version.`);
|
|
3783
|
+
}
|
|
3784
|
+
const hasComplexFields = block.fields?.some((field) => {
|
|
3785
|
+
const complexTypes = ["code", "json", "richText", "blocks", "array"];
|
|
3786
|
+
return complexTypes.includes(field.type);
|
|
3787
|
+
});
|
|
3788
|
+
if (hasComplexFields) {
|
|
3789
|
+
console.warn(`\u26A0\uFE0F Block "${block.slug}" contains complex field types that may not render consistently in email clients.`);
|
|
3790
|
+
}
|
|
3791
|
+
});
|
|
3792
|
+
};
|
|
3793
|
+
var createEmailSafeBlocks = (customBlocks = []) => {
|
|
3794
|
+
validateEmailBlocks(customBlocks);
|
|
3795
|
+
const baseBlocks = [
|
|
3796
|
+
{
|
|
3797
|
+
slug: "button",
|
|
3798
|
+
fields: [
|
|
3799
|
+
{
|
|
3800
|
+
name: "text",
|
|
3801
|
+
type: "text",
|
|
3802
|
+
label: "Button Text",
|
|
3803
|
+
required: true
|
|
3804
|
+
},
|
|
3805
|
+
{
|
|
3806
|
+
name: "url",
|
|
3807
|
+
type: "text",
|
|
3808
|
+
label: "Button URL",
|
|
3809
|
+
required: true,
|
|
3810
|
+
admin: {
|
|
3811
|
+
description: "Enter the full URL (including https://)"
|
|
3812
|
+
}
|
|
3813
|
+
},
|
|
3814
|
+
{
|
|
3815
|
+
name: "style",
|
|
3816
|
+
type: "select",
|
|
3817
|
+
label: "Button Style",
|
|
3818
|
+
defaultValue: "primary",
|
|
3819
|
+
options: [
|
|
3820
|
+
{ label: "Primary", value: "primary" },
|
|
3821
|
+
{ label: "Secondary", value: "secondary" },
|
|
3822
|
+
{ label: "Outline", value: "outline" }
|
|
3823
|
+
]
|
|
3784
3824
|
}
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
defaultValue: false
|
|
3825
|
+
],
|
|
3826
|
+
interfaceName: "EmailButton",
|
|
3827
|
+
labels: {
|
|
3828
|
+
singular: "Button",
|
|
3829
|
+
plural: "Buttons"
|
|
3791
3830
|
}
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3831
|
+
},
|
|
3832
|
+
{
|
|
3833
|
+
slug: "divider",
|
|
3834
|
+
fields: [
|
|
3835
|
+
{
|
|
3836
|
+
name: "style",
|
|
3837
|
+
type: "select",
|
|
3838
|
+
label: "Divider Style",
|
|
3839
|
+
defaultValue: "solid",
|
|
3840
|
+
options: [
|
|
3841
|
+
{ label: "Solid", value: "solid" },
|
|
3842
|
+
{ label: "Dashed", value: "dashed" },
|
|
3843
|
+
{ label: "Dotted", value: "dotted" }
|
|
3844
|
+
]
|
|
3845
|
+
}
|
|
3846
|
+
],
|
|
3847
|
+
interfaceName: "EmailDivider",
|
|
3848
|
+
labels: {
|
|
3849
|
+
singular: "Divider",
|
|
3850
|
+
plural: "Dividers"
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
];
|
|
3854
|
+
return [
|
|
3855
|
+
...baseBlocks,
|
|
3856
|
+
...customBlocks
|
|
3857
|
+
];
|
|
3858
|
+
};
|
|
3859
|
+
|
|
3860
|
+
// src/fields/emailContent.ts
|
|
3861
|
+
var createEmailSafeFeatures = (additionalBlocks) => {
|
|
3862
|
+
const baseBlocks = [
|
|
3863
|
+
{
|
|
3864
|
+
slug: "button",
|
|
3865
|
+
fields: [
|
|
3866
|
+
{
|
|
3867
|
+
name: "text",
|
|
3868
|
+
type: "text",
|
|
3869
|
+
label: "Button Text",
|
|
3870
|
+
required: true
|
|
3871
|
+
},
|
|
3872
|
+
{
|
|
3873
|
+
name: "url",
|
|
3874
|
+
type: "text",
|
|
3875
|
+
label: "Button URL",
|
|
3876
|
+
required: true,
|
|
3877
|
+
admin: {
|
|
3878
|
+
description: "Enter the full URL (including https://)"
|
|
3826
3879
|
}
|
|
3827
|
-
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
name: "style",
|
|
3883
|
+
type: "select",
|
|
3884
|
+
label: "Button Style",
|
|
3885
|
+
defaultValue: "primary",
|
|
3886
|
+
options: [
|
|
3887
|
+
{ label: "Primary", value: "primary" },
|
|
3888
|
+
{ label: "Secondary", value: "secondary" },
|
|
3889
|
+
{ label: "Outline", value: "outline" }
|
|
3890
|
+
]
|
|
3891
|
+
}
|
|
3892
|
+
],
|
|
3893
|
+
interfaceName: "EmailButton",
|
|
3894
|
+
labels: {
|
|
3895
|
+
singular: "Button",
|
|
3896
|
+
plural: "Buttons"
|
|
3897
|
+
}
|
|
3898
|
+
},
|
|
3899
|
+
{
|
|
3900
|
+
slug: "divider",
|
|
3901
|
+
fields: [
|
|
3902
|
+
{
|
|
3903
|
+
name: "style",
|
|
3904
|
+
type: "select",
|
|
3905
|
+
label: "Divider Style",
|
|
3906
|
+
defaultValue: "solid",
|
|
3907
|
+
options: [
|
|
3908
|
+
{ label: "Solid", value: "solid" },
|
|
3909
|
+
{ label: "Dashed", value: "dashed" },
|
|
3910
|
+
{ label: "Dotted", value: "dotted" }
|
|
3911
|
+
]
|
|
3912
|
+
}
|
|
3913
|
+
],
|
|
3914
|
+
interfaceName: "EmailDivider",
|
|
3915
|
+
labels: {
|
|
3916
|
+
singular: "Divider",
|
|
3917
|
+
plural: "Dividers"
|
|
3828
3918
|
}
|
|
3829
3919
|
}
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3920
|
+
];
|
|
3921
|
+
const allBlocks = [
|
|
3922
|
+
...baseBlocks,
|
|
3923
|
+
...additionalBlocks || []
|
|
3924
|
+
];
|
|
3925
|
+
return [
|
|
3926
|
+
// Toolbars
|
|
3927
|
+
(0, import_richtext_lexical.FixedToolbarFeature)(),
|
|
3928
|
+
// Fixed toolbar at the top
|
|
3929
|
+
(0, import_richtext_lexical.InlineToolbarFeature)(),
|
|
3930
|
+
// Floating toolbar when text is selected
|
|
3931
|
+
// Basic text formatting
|
|
3932
|
+
(0, import_richtext_lexical.BoldFeature)(),
|
|
3933
|
+
(0, import_richtext_lexical.ItalicFeature)(),
|
|
3934
|
+
(0, import_richtext_lexical.UnderlineFeature)(),
|
|
3935
|
+
(0, import_richtext_lexical.StrikethroughFeature)(),
|
|
3936
|
+
// Links with enhanced configuration
|
|
3937
|
+
(0, import_richtext_lexical.LinkFeature)({
|
|
3938
|
+
fields: [
|
|
3939
|
+
{
|
|
3940
|
+
name: "url",
|
|
3941
|
+
type: "text",
|
|
3942
|
+
required: true,
|
|
3943
|
+
admin: {
|
|
3944
|
+
description: "Enter the full URL (including https://)"
|
|
3945
|
+
}
|
|
3946
|
+
},
|
|
3947
|
+
{
|
|
3948
|
+
name: "newTab",
|
|
3949
|
+
type: "checkbox",
|
|
3950
|
+
label: "Open in new tab",
|
|
3951
|
+
defaultValue: false
|
|
3952
|
+
}
|
|
3953
|
+
]
|
|
3954
|
+
}),
|
|
3955
|
+
// Lists
|
|
3956
|
+
(0, import_richtext_lexical.OrderedListFeature)(),
|
|
3957
|
+
(0, import_richtext_lexical.UnorderedListFeature)(),
|
|
3958
|
+
// Headings - limited to h1, h2, h3 for email compatibility
|
|
3959
|
+
(0, import_richtext_lexical.HeadingFeature)({
|
|
3960
|
+
enabledHeadingSizes: ["h1", "h2", "h3"]
|
|
3961
|
+
}),
|
|
3962
|
+
// Basic paragraph and alignment
|
|
3963
|
+
(0, import_richtext_lexical.ParagraphFeature)(),
|
|
3964
|
+
(0, import_richtext_lexical.AlignFeature)(),
|
|
3965
|
+
// Blockquotes
|
|
3966
|
+
(0, import_richtext_lexical.BlockquoteFeature)(),
|
|
3967
|
+
// Upload feature for images
|
|
3968
|
+
(0, import_richtext_lexical.UploadFeature)({
|
|
3969
|
+
collections: {
|
|
3970
|
+
media: {
|
|
3971
|
+
fields: [
|
|
3972
|
+
{
|
|
3973
|
+
name: "caption",
|
|
3974
|
+
type: "text",
|
|
3975
|
+
admin: {
|
|
3976
|
+
description: "Optional caption for the image"
|
|
3977
|
+
}
|
|
3978
|
+
},
|
|
3979
|
+
{
|
|
3980
|
+
name: "altText",
|
|
3981
|
+
type: "text",
|
|
3982
|
+
label: "Alt Text",
|
|
3983
|
+
required: true,
|
|
3984
|
+
admin: {
|
|
3985
|
+
description: "Alternative text for accessibility and when image cannot be displayed"
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
]
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
}),
|
|
3992
|
+
// Custom blocks for email-specific content
|
|
3993
|
+
(0, import_richtext_lexical.BlocksFeature)({
|
|
3994
|
+
blocks: allBlocks
|
|
3995
|
+
})
|
|
3996
|
+
];
|
|
3997
|
+
};
|
|
3998
|
+
var createEmailLexicalEditor = (customBlocks = []) => {
|
|
3999
|
+
const emailSafeBlocks = createEmailSafeBlocks(customBlocks);
|
|
4000
|
+
return (0, import_richtext_lexical.lexicalEditor)({
|
|
4001
|
+
features: [
|
|
4002
|
+
// Toolbars
|
|
4003
|
+
(0, import_richtext_lexical.FixedToolbarFeature)(),
|
|
4004
|
+
(0, import_richtext_lexical.InlineToolbarFeature)(),
|
|
4005
|
+
// Basic text formatting
|
|
4006
|
+
(0, import_richtext_lexical.BoldFeature)(),
|
|
4007
|
+
(0, import_richtext_lexical.ItalicFeature)(),
|
|
4008
|
+
(0, import_richtext_lexical.UnderlineFeature)(),
|
|
4009
|
+
(0, import_richtext_lexical.StrikethroughFeature)(),
|
|
4010
|
+
// Links with enhanced configuration
|
|
4011
|
+
(0, import_richtext_lexical.LinkFeature)({
|
|
3836
4012
|
fields: [
|
|
3837
|
-
{
|
|
3838
|
-
name: "text",
|
|
3839
|
-
type: "text",
|
|
3840
|
-
label: "Button Text",
|
|
3841
|
-
required: true
|
|
3842
|
-
},
|
|
3843
4013
|
{
|
|
3844
4014
|
name: "url",
|
|
3845
4015
|
type: "text",
|
|
3846
|
-
label: "Button URL",
|
|
3847
4016
|
required: true,
|
|
3848
4017
|
admin: {
|
|
3849
4018
|
description: "Enter the full URL (including https://)"
|
|
3850
4019
|
}
|
|
3851
4020
|
},
|
|
3852
4021
|
{
|
|
3853
|
-
name: "
|
|
3854
|
-
type: "
|
|
3855
|
-
label: "
|
|
3856
|
-
defaultValue:
|
|
3857
|
-
options: [
|
|
3858
|
-
{ label: "Primary", value: "primary" },
|
|
3859
|
-
{ label: "Secondary", value: "secondary" },
|
|
3860
|
-
{ label: "Outline", value: "outline" }
|
|
3861
|
-
]
|
|
4022
|
+
name: "newTab",
|
|
4023
|
+
type: "checkbox",
|
|
4024
|
+
label: "Open in new tab",
|
|
4025
|
+
defaultValue: false
|
|
3862
4026
|
}
|
|
3863
|
-
]
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
4027
|
+
]
|
|
4028
|
+
}),
|
|
4029
|
+
// Lists
|
|
4030
|
+
(0, import_richtext_lexical.OrderedListFeature)(),
|
|
4031
|
+
(0, import_richtext_lexical.UnorderedListFeature)(),
|
|
4032
|
+
// Headings - limited to h1, h2, h3 for email compatibility
|
|
4033
|
+
(0, import_richtext_lexical.HeadingFeature)({
|
|
4034
|
+
enabledHeadingSizes: ["h1", "h2", "h3"]
|
|
4035
|
+
}),
|
|
4036
|
+
// Basic paragraph and alignment
|
|
4037
|
+
(0, import_richtext_lexical.ParagraphFeature)(),
|
|
4038
|
+
(0, import_richtext_lexical.AlignFeature)(),
|
|
4039
|
+
// Blockquotes
|
|
4040
|
+
(0, import_richtext_lexical.BlockquoteFeature)(),
|
|
4041
|
+
// Upload feature for images
|
|
4042
|
+
(0, import_richtext_lexical.UploadFeature)({
|
|
4043
|
+
collections: {
|
|
4044
|
+
media: {
|
|
4045
|
+
fields: [
|
|
4046
|
+
{
|
|
4047
|
+
name: "caption",
|
|
4048
|
+
type: "text",
|
|
4049
|
+
admin: {
|
|
4050
|
+
description: "Optional caption for the image"
|
|
4051
|
+
}
|
|
4052
|
+
},
|
|
4053
|
+
{
|
|
4054
|
+
name: "altText",
|
|
4055
|
+
type: "text",
|
|
4056
|
+
label: "Alt Text",
|
|
4057
|
+
required: true,
|
|
4058
|
+
admin: {
|
|
4059
|
+
description: "Alternative text for accessibility and when image cannot be displayed"
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
3882
4062
|
]
|
|
3883
4063
|
}
|
|
3884
|
-
],
|
|
3885
|
-
interfaceName: "EmailDivider",
|
|
3886
|
-
labels: {
|
|
3887
|
-
singular: "Divider",
|
|
3888
|
-
plural: "Dividers"
|
|
3889
4064
|
}
|
|
3890
|
-
}
|
|
4065
|
+
}),
|
|
4066
|
+
// Email-safe blocks (processed server-side)
|
|
4067
|
+
(0, import_richtext_lexical.BlocksFeature)({
|
|
4068
|
+
blocks: emailSafeBlocks
|
|
4069
|
+
})
|
|
3891
4070
|
]
|
|
3892
|
-
})
|
|
3893
|
-
|
|
4071
|
+
});
|
|
4072
|
+
};
|
|
4073
|
+
var emailSafeFeatures = createEmailSafeFeatures();
|
|
3894
4074
|
var createEmailContentField = (overrides) => {
|
|
4075
|
+
const editor = overrides?.editor || createEmailLexicalEditor(overrides?.additionalBlocks);
|
|
3895
4076
|
return {
|
|
3896
4077
|
name: "content",
|
|
3897
4078
|
type: "richText",
|
|
3898
4079
|
required: true,
|
|
3899
|
-
editor
|
|
3900
|
-
features: emailSafeFeatures
|
|
3901
|
-
}),
|
|
4080
|
+
editor,
|
|
3902
4081
|
admin: {
|
|
3903
4082
|
description: "Email content with limited formatting for compatibility",
|
|
3904
4083
|
...overrides?.admin
|
|
@@ -3923,6 +4102,7 @@ var createBroadcastInlinePreviewField = () => {
|
|
|
3923
4102
|
// src/collections/Broadcasts.ts
|
|
3924
4103
|
var createBroadcastsCollection = (pluginConfig) => {
|
|
3925
4104
|
const hasProviders = !!(pluginConfig.providers?.broadcast || pluginConfig.providers?.resend);
|
|
4105
|
+
const customizations = pluginConfig.customizations?.broadcasts;
|
|
3926
4106
|
return {
|
|
3927
4107
|
slug: "broadcasts",
|
|
3928
4108
|
labels: {
|
|
@@ -3943,6 +4123,8 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
3943
4123
|
description: "Email subject line"
|
|
3944
4124
|
}
|
|
3945
4125
|
},
|
|
4126
|
+
// Add any additional fields from customizations after subject
|
|
4127
|
+
...customizations?.additionalFields || [],
|
|
3946
4128
|
{
|
|
3947
4129
|
type: "row",
|
|
3948
4130
|
fields: [
|
|
@@ -3964,11 +4146,16 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
3964
4146
|
description: "Preview text shown in email clients"
|
|
3965
4147
|
}
|
|
3966
4148
|
},
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
4149
|
+
// Apply content field customization if provided
|
|
4150
|
+
// Process blocks server-side to avoid client serialization issues
|
|
4151
|
+
(() => {
|
|
4152
|
+
const emailEditor = createEmailLexicalEditor(customizations?.customBlocks);
|
|
4153
|
+
const baseField = createEmailContentField({
|
|
4154
|
+
admin: { description: "Email content" },
|
|
4155
|
+
editor: emailEditor
|
|
4156
|
+
});
|
|
4157
|
+
return customizations?.fieldOverrides?.content ? customizations.fieldOverrides.content(baseField) : baseField;
|
|
4158
|
+
})()
|
|
3972
4159
|
]
|
|
3973
4160
|
},
|
|
3974
4161
|
{
|