mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 16:23:23 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff788c1ecf | ||
| c12438aaa2 | |||
| 4dcbc1446a | |||
|
|
72f3d7f66d | ||
| ecc0b0a73e | |||
| a959673fc1 | |||
| 8809db6aff |
@@ -38,50 +38,55 @@ const customEmail = await sendEmail<MyEmail>(payload, {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## ID Type Compatibility
|
## Compatibility
|
||||||
|
|
||||||
The plugin works with both:
|
The plugin works with:
|
||||||
- **String IDs**: `id: string`
|
- **String IDs**: `id: string`
|
||||||
- **Number IDs**: `id: number`
|
- **Number IDs**: `id: number`
|
||||||
|
- **Nullable fields**: Fields can be `null`, `undefined`, or have values
|
||||||
|
- **Generated types**: Works with `payload generate:types` output
|
||||||
|
|
||||||
Your Payload configuration determines which type is used. The plugin automatically adapts to your setup.
|
Your Payload configuration determines which types are used. The plugin automatically adapts to your setup.
|
||||||
|
|
||||||
## Type Definitions
|
## Type Definitions
|
||||||
|
|
||||||
The base interfaces provided by the plugin:
|
The base interfaces provided by the plugin:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
// JSON value type that matches Payload's JSON field type
|
||||||
|
type JSONValue = string | number | boolean | { [k: string]: unknown } | unknown[] | null | undefined
|
||||||
|
|
||||||
interface BaseEmailDocument {
|
interface BaseEmailDocument {
|
||||||
id: string | number
|
id: string | number
|
||||||
template?: any
|
template?: any
|
||||||
to: string[]
|
to: string[]
|
||||||
cc?: string[]
|
cc?: string[] | null
|
||||||
bcc?: string[]
|
bcc?: string[] | null
|
||||||
from?: string
|
from?: string | null
|
||||||
replyTo?: string
|
replyTo?: string | null
|
||||||
subject: string
|
subject: string
|
||||||
html: string
|
html: string
|
||||||
text?: string
|
text?: string | null
|
||||||
variables?: Record<string, any>
|
variables?: JSONValue // Supports any JSON-compatible value
|
||||||
scheduledAt?: string
|
scheduledAt?: string | null
|
||||||
sentAt?: string
|
sentAt?: string | null
|
||||||
status?: 'pending' | 'processing' | 'sent' | 'failed'
|
status?: 'pending' | 'processing' | 'sent' | 'failed' | null
|
||||||
attempts?: number
|
attempts?: number | null
|
||||||
lastAttemptAt?: string
|
lastAttemptAt?: string | null
|
||||||
error?: string
|
error?: string | null
|
||||||
priority?: number
|
priority?: number | null
|
||||||
createdAt?: string
|
createdAt?: string | null
|
||||||
updatedAt?: string
|
updatedAt?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BaseEmailTemplateDocument {
|
interface BaseEmailTemplateDocument {
|
||||||
id: string | number
|
id: string | number
|
||||||
name: string
|
name: string
|
||||||
slug: string
|
slug: string
|
||||||
subject?: string
|
subject?: string | null
|
||||||
content?: any
|
content?: any
|
||||||
createdAt?: string
|
createdAt?: string | null
|
||||||
updatedAt?: string
|
updatedAt?: string | null
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@xtr-dev/payload-mailing",
|
"name": "@xtr-dev/payload-mailing",
|
||||||
"version": "0.1.13",
|
"version": "0.1.15",
|
||||||
"description": "Template-based email system with scheduling and job processing for PayloadCMS",
|
"description": "Template-based email system with scheduling and job processing for PayloadCMS",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -83,12 +83,22 @@ export const sendEmail = async <TEmail extends BaseEmailDocument = BaseEmailDocu
|
|||||||
if (emailData.to) {
|
if (emailData.to) {
|
||||||
emailData.to = parseAndValidateEmails(emailData.to as string | string[])
|
emailData.to = parseAndValidateEmails(emailData.to as string | string[])
|
||||||
}
|
}
|
||||||
if (emailData.cc) {
|
if (emailData.cc && emailData.cc !== null) {
|
||||||
emailData.cc = parseAndValidateEmails(emailData.cc as string | string[])
|
emailData.cc = parseAndValidateEmails(emailData.cc as string | string[])
|
||||||
}
|
}
|
||||||
if (emailData.bcc) {
|
if (emailData.bcc && emailData.bcc !== null) {
|
||||||
emailData.bcc = parseAndValidateEmails(emailData.bcc as string | string[])
|
emailData.bcc = parseAndValidateEmails(emailData.bcc as string | string[])
|
||||||
}
|
}
|
||||||
|
if (emailData.replyTo && emailData.replyTo !== null) {
|
||||||
|
const validated = parseAndValidateEmails(emailData.replyTo as string | string[])
|
||||||
|
// replyTo should be a single email, so take the first one if array
|
||||||
|
emailData.replyTo = validated && validated.length > 0 ? validated[0] : undefined
|
||||||
|
}
|
||||||
|
if (emailData.from && emailData.from !== null) {
|
||||||
|
const validated = parseAndValidateEmails(emailData.from as string | string[])
|
||||||
|
// from should be a single email, so take the first one if array
|
||||||
|
emailData.from = validated && validated.length > 0 ? validated[0] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
// Create the email in the collection with proper typing
|
// Create the email in the collection with proper typing
|
||||||
const email = await payload.create({
|
const email = await payload.create({
|
||||||
|
|||||||
@@ -2,38 +2,41 @@ import { Payload } from 'payload'
|
|||||||
import type { CollectionConfig, RichTextField } from 'payload'
|
import type { CollectionConfig, RichTextField } from 'payload'
|
||||||
import { Transporter } from 'nodemailer'
|
import { Transporter } from 'nodemailer'
|
||||||
|
|
||||||
// Generic base interfaces that work with any ID type
|
// JSON value type that matches Payload's JSON field type
|
||||||
|
export type JSONValue = string | number | boolean | { [k: string]: unknown } | unknown[] | null | undefined
|
||||||
|
|
||||||
|
// Generic base interfaces that work with any ID type and null values
|
||||||
export interface BaseEmailDocument {
|
export interface BaseEmailDocument {
|
||||||
id: string | number
|
id: string | number
|
||||||
template?: any
|
template?: any
|
||||||
to: string[]
|
to: string[]
|
||||||
cc?: string[]
|
cc?: string[] | null
|
||||||
bcc?: string[]
|
bcc?: string[] | null
|
||||||
from?: string
|
from?: string | null
|
||||||
replyTo?: string
|
replyTo?: string | null
|
||||||
subject: string
|
subject: string
|
||||||
html: string
|
html: string
|
||||||
text?: string
|
text?: string | null
|
||||||
variables?: Record<string, any>
|
variables?: JSONValue
|
||||||
scheduledAt?: string
|
scheduledAt?: string | null
|
||||||
sentAt?: string
|
sentAt?: string | null
|
||||||
status?: 'pending' | 'processing' | 'sent' | 'failed'
|
status?: 'pending' | 'processing' | 'sent' | 'failed' | null
|
||||||
attempts?: number
|
attempts?: number | null
|
||||||
lastAttemptAt?: string
|
lastAttemptAt?: string | null
|
||||||
error?: string
|
error?: string | null
|
||||||
priority?: number
|
priority?: number | null
|
||||||
createdAt?: string
|
createdAt?: string | null
|
||||||
updatedAt?: string
|
updatedAt?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BaseEmailTemplateDocument {
|
export interface BaseEmailTemplateDocument {
|
||||||
id: string | number
|
id: string | number
|
||||||
name: string
|
name: string
|
||||||
slug: string
|
slug: string
|
||||||
subject?: string
|
subject?: string | null
|
||||||
content?: any
|
content?: any
|
||||||
createdAt?: string
|
createdAt?: string | null
|
||||||
updatedAt?: string
|
updatedAt?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BaseEmail<TEmail extends BaseEmailDocument = BaseEmailDocument, TEmailTemplate extends BaseEmailTemplateDocument = BaseEmailTemplateDocument> = Omit<TEmail, 'id' | 'template'> & {template: Omit<TEmailTemplate, 'id'> | TEmailTemplate['id'] | undefined | null}
|
export type BaseEmail<TEmail extends BaseEmailDocument = BaseEmailDocument, TEmailTemplate extends BaseEmailTemplateDocument = BaseEmailTemplateDocument> = Omit<TEmail, 'id' | 'template'> & {template: Omit<TEmailTemplate, 'id'> | TEmailTemplate['id'] | undefined | null}
|
||||||
@@ -75,23 +78,23 @@ export interface MailingTransportConfig {
|
|||||||
|
|
||||||
export interface QueuedEmail {
|
export interface QueuedEmail {
|
||||||
id: string
|
id: string
|
||||||
template?: string
|
template?: string | null
|
||||||
to: string[]
|
to: string[]
|
||||||
cc?: string[]
|
cc?: string[] | null
|
||||||
bcc?: string[]
|
bcc?: string[] | null
|
||||||
from?: string
|
from?: string | null
|
||||||
replyTo?: string
|
replyTo?: string | null
|
||||||
subject: string
|
subject: string
|
||||||
html: string
|
html: string
|
||||||
text?: string
|
text?: string | null
|
||||||
variables?: Record<string, any>
|
variables?: JSONValue
|
||||||
scheduledAt?: string
|
scheduledAt?: string | null
|
||||||
sentAt?: string
|
sentAt?: string | null
|
||||||
status: 'pending' | 'processing' | 'sent' | 'failed'
|
status: 'pending' | 'processing' | 'sent' | 'failed'
|
||||||
attempts: number
|
attempts: number
|
||||||
lastAttemptAt?: string
|
lastAttemptAt?: string | null
|
||||||
error?: string
|
error?: string | null
|
||||||
priority?: number
|
priority?: number | null
|
||||||
createdAt: string
|
createdAt: string
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user