mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 08:13:23 +00:00
Refactor email types for enhanced consistency and type safety
- Replace `EmailTemplate` with `BaseEmailTemplate` for stricter type validation. - Update `sendEmail` and `sendEmailTask` to utilize refined `BaseEmail` structure. - Simplify type definitions in `MailingService` and related modules.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { sendEmail } from '../sendEmail.js'
|
import { sendEmail } from '../sendEmail.js'
|
||||||
import { Email } from '../payload-types.js'
|
import {Email, EmailTemplate} from '../payload-types.js'
|
||||||
import {BaseEmail} from "../types/index.js"
|
import {BaseEmail} from "../types/index.js"
|
||||||
|
|
||||||
export interface SendEmailTaskInput {
|
export interface SendEmailTaskInput {
|
||||||
@@ -161,7 +161,7 @@ export const sendEmailJob = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Use the sendEmail helper to create the email
|
// Use the sendEmail helper to create the email
|
||||||
const email = await sendEmail<BaseEmail>(payload, sendEmailOptions)
|
const email = await sendEmail<Email, EmailTemplate>(payload, sendEmailOptions)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
output: {
|
output: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Payload } from 'payload'
|
import { Payload } from 'payload'
|
||||||
import { getMailing, renderTemplate, parseAndValidateEmails } from './utils/helpers.js'
|
import { getMailing, renderTemplate, parseAndValidateEmails } from './utils/helpers.js'
|
||||||
import {Email} from "./payload-types.js"
|
import {Email, EmailTemplate} from "./payload-types.js"
|
||||||
import {BaseEmail} from "./types/index.js"
|
import {BaseEmail} from "./types/index.js"
|
||||||
|
|
||||||
// Options for sending emails
|
// Options for sending emails
|
||||||
@@ -36,14 +36,14 @@ export interface SendEmailOptions<T extends BaseEmail = BaseEmail> {
|
|||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const sendEmail = async <T extends BaseEmail = BaseEmail, ID = string | number>(
|
export const sendEmail = async <TEmail extends Email = Email, TEmailTemplate extends EmailTemplate = EmailTemplate>(
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
options: SendEmailOptions<T>
|
options: SendEmailOptions<BaseEmail<TEmail, TEmailTemplate>>
|
||||||
): Promise<T & {id: ID}> => {
|
): Promise<TEmail> => {
|
||||||
const mailing = getMailing(payload)
|
const mailing = getMailing(payload)
|
||||||
const collectionSlug = options.collectionSlug || mailing.collections.emails || 'emails'
|
const collectionSlug = options.collectionSlug || mailing.collections.emails || 'emails'
|
||||||
|
|
||||||
let emailData: Partial<T> = { ...options.data } as Partial<T>
|
let emailData: Partial<TEmail> = { ...options.data } as Partial<TEmail>
|
||||||
|
|
||||||
// If using a template, render it first
|
// If using a template, render it first
|
||||||
if (options.template) {
|
if (options.template) {
|
||||||
@@ -59,7 +59,7 @@ export const sendEmail = async <T extends BaseEmail = BaseEmail, ID = string | n
|
|||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
text,
|
text,
|
||||||
} as Partial<T>
|
} as Partial<TEmail>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required fields
|
// Validate required fields
|
||||||
@@ -97,7 +97,7 @@ export const sendEmail = async <T extends BaseEmail = BaseEmail, ID = string | n
|
|||||||
data: emailData
|
data: emailData
|
||||||
})
|
})
|
||||||
|
|
||||||
return email as T & {id: ID}
|
return email as TEmail
|
||||||
}
|
}
|
||||||
|
|
||||||
export default sendEmail
|
export default sendEmail
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import {
|
|||||||
MailingPluginConfig,
|
MailingPluginConfig,
|
||||||
TemplateVariables,
|
TemplateVariables,
|
||||||
MailingService as IMailingService,
|
MailingService as IMailingService,
|
||||||
EmailTemplate,
|
|
||||||
QueuedEmail,
|
|
||||||
MailingTransportConfig,
|
MailingTransportConfig,
|
||||||
BaseEmail
|
BaseEmail, BaseEmailTemplate
|
||||||
} from '../types/index.js'
|
} from '../types/index.js'
|
||||||
import { serializeRichTextToHTML, serializeRichTextToText } from '../utils/richTextSerializer.js'
|
import { serializeRichTextToHTML, serializeRichTextToText } from '../utils/richTextSerializer.js'
|
||||||
|
|
||||||
@@ -287,7 +285,7 @@ export class MailingService implements IMailingService {
|
|||||||
const email = await this.payload.findByID({
|
const email = await this.payload.findByID({
|
||||||
collection: this.emailsCollection as any,
|
collection: this.emailsCollection as any,
|
||||||
id: emailId,
|
id: emailId,
|
||||||
}) as QueuedEmail
|
}) as BaseEmail
|
||||||
|
|
||||||
const newAttempts = (email.attempts || 0) + 1
|
const newAttempts = (email.attempts || 0) + 1
|
||||||
|
|
||||||
@@ -302,7 +300,7 @@ export class MailingService implements IMailingService {
|
|||||||
return newAttempts
|
return newAttempts
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getTemplateBySlug(templateSlug: string): Promise<EmailTemplate | null> {
|
private async getTemplateBySlug(templateSlug: string): Promise<BaseEmailTemplate | null> {
|
||||||
try {
|
try {
|
||||||
const { docs } = await this.payload.find({
|
const { docs } = await this.payload.find({
|
||||||
collection: this.templatesCollection as any,
|
collection: this.templatesCollection as any,
|
||||||
@@ -314,7 +312,7 @@ export class MailingService implements IMailingService {
|
|||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
return docs.length > 0 ? docs[0] as EmailTemplate : null
|
return docs.length > 0 ? docs[0] as BaseEmailTemplate : null
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Template with slug '${templateSlug}' not found:`, error)
|
console.error(`Template with slug '${templateSlug}' not found:`, error)
|
||||||
return null
|
return null
|
||||||
@@ -379,7 +377,7 @@ export class MailingService implements IMailingService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async renderEmailTemplate(template: EmailTemplate, variables: Record<string, any> = {}): Promise<{ html: string; text: string }> {
|
private async renderEmailTemplate(template: BaseEmailTemplate, variables: Record<string, any> = {}): Promise<{ html: string; text: string }> {
|
||||||
if (!template.content) {
|
if (!template.content) {
|
||||||
return { html: '', text: '' }
|
return { html: '', text: '' }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { Payload } from 'payload'
|
import { Payload } from 'payload'
|
||||||
import type { CollectionConfig, RichTextField } from 'payload'
|
import type { CollectionConfig, RichTextField } from 'payload'
|
||||||
import { Transporter } from 'nodemailer'
|
import { Transporter } from 'nodemailer'
|
||||||
import {Email} from "../payload-types.js"
|
import {Email, EmailTemplate} from "../payload-types.js"
|
||||||
|
|
||||||
export type BaseEmail<TEmail = Email, TEmailTemplate = EmailTemplate> = Omit<TEmail, 'id' | 'template'> & {template: Omit<TEmailTemplate, 'id'>}
|
export type BaseEmail<TEmail extends Email = Email, TEmailTemplate extends EmailTemplate = EmailTemplate> = Omit<TEmail, 'id' | 'template'> & {template: Omit<TEmailTemplate, 'id'> | TEmailTemplate['id'] | undefined | null}
|
||||||
|
|
||||||
|
export type BaseEmailTemplate<TEmailTemplate extends EmailTemplate = EmailTemplate> = Omit<TEmailTemplate, 'id'>
|
||||||
|
|
||||||
export type TemplateRendererHook = (template: string, variables: Record<string, any>) => string | Promise<string>
|
export type TemplateRendererHook = (template: string, variables: Record<string, any>) => string | Promise<string>
|
||||||
|
|
||||||
@@ -37,16 +39,6 @@ export interface MailingTransportConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EmailTemplate {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
slug: string
|
|
||||||
subject: string
|
|
||||||
content: any // Lexical editor state
|
|
||||||
createdAt: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface QueuedEmail {
|
export interface QueuedEmail {
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
Reference in New Issue
Block a user